const API_BASE = (import.meta as any).env?.VITE_API_BASE || '';
const USE_MOCK_ENV = (import.meta as any).env?.VITE_USE_MOCK;
const USE_BACKEND_ENV = (import.meta as any).env?.VITE_USE_BACKEND;

// 默认使用后端，除非明确设置为 'false'
const USE_MOCK = USE_MOCK_ENV === 'true';
const USE_BACKEND = USE_BACKEND_ENV !== 'false'; // 默认 true（未设置或设置为 'true' 都使用后端）

// 后端可用性状态（缓存检查结果）
let backendCheckAttempted = false;
let useBackend = false;

export async function api<T>(path: string, init: RequestInit = {}): Promise<T> {
  // 如果明确设置了使用mock，直接使用mock
  if (USE_MOCK) {
    const mockError = new Error('USE_MOCK_DATA') as any;
    mockError.isMock = true;
    mockError.path = path;
    mockError.init = init;
    throw mockError;
  }
  
  // 默认使用后端（USE_BACKEND 默认是 true）
  // 只有明确设置为 false 时才不使用后端
  if (!USE_BACKEND) {
    const mockError = new Error('USE_MOCK_DATA') as any;
    mockError.isMock = true;
    mockError.path = path;
    mockError.init = init;
    throw mockError;
  }

  // 只在第一次请求时检查后端可用性
  // 注意：不在这里检查，直接尝试实际请求，如果失败再降级
  if (!backendCheckAttempted) {
    backendCheckAttempted = true;
    // 默认假设后端可用，直接尝试连接
    useBackend = true;
  }

  // 如果已确认后端不可用，直接使用mock
  if (!useBackend) {
    const mockError = new Error('USE_MOCK_DATA') as any;
    mockError.isMock = true;
    mockError.path = path;
    mockError.init = init;
    throw mockError;
  }

  // 后端可用，发起实际请求
  // 优先使用 Vite 代理（避免 CORS 问题），如果代理不可用则使用完整 URL
  const token = localStorage.getItem('token') || '';
  
  // 判断是否使用代理（开发环境通常使用代理）
  // 优先使用 Vite 代理（相对路径），避免 CORS 问题
  let url: string;
  if (API_BASE) {
    url = `${API_BASE}${path}`;
  } else {
    // 使用相对路径，通过 Vite 代理转发到后端
    // Vite 代理配置在 vite.config.ts 中，会自动转发到 http://localhost:8090
    url = path;
  }
  
  try {
    const fetchOptions: RequestInit = {
      method: init.method || 'GET',
      headers: {
        'Content-Type': 'application/json',
        Authorization: token ? `Bearer ${token}` : '',
        ...(init.headers || {}),
      },
      ...init,
    };
    
    // 使用 AbortSignal.timeout 如果支持，否则使用 setTimeout
    if (typeof AbortSignal.timeout === 'function') {
      fetchOptions.signal = AbortSignal.timeout(10000); // 增加到 10 秒
    }
    
    const resp = await fetch(url, fetchOptions);
    if (resp.status === 401) {
      // 401未授权：清除token并跳转到登录页
      localStorage.removeItem('token');
      localStorage.removeItem('role');
      localStorage.removeItem('dev_mode');
      // 抛出错误，让调用者处理
      const error = new Error('未登录') as any;
      error.status = 401;
      error.path = path;
      throw error;
    }
    if (resp.status === 204) return undefined as unknown as T;
    
    // 读取响应体（只能读取一次）
    const text = await resp.text();
    if (!text) {
      if (!resp.ok) {
        throw new Error('请求失败');
      }
      return undefined as unknown as T;
    }
    
    let json: any;
    try {
      json = JSON.parse(text);
    } catch {
      // 如果不是JSON格式，直接抛出错误
      if (!resp.ok) {
        throw new Error(text || '请求失败');
      }
      throw new Error('响应格式错误');
    }
    
    if (!resp.ok) {
      // 后端使用ResultUtil格式：{ code, msg, data }
      if (json && typeof json === 'object' && 'msg' in json) {
        throw new Error(json.msg);
      }
      throw new Error(json.error || '请求失败');
    }
    
    // 适配后端ResultUtil格式：{ code, msg, data, timestamp }
    // 如果响应包含code字段，说明是ResultUtil格式
    if (json && typeof json === 'object' && 'code' in json) {
      const code = json.code;
      // 200表示成功（HttpStatus.SUCCESS）
      if (code === 200) {
        // 返回data字段中的实际数据
        return (json.data !== undefined ? json.data : json) as T;
      } else {
        // code不是200，说明是错误响应
        throw new Error(json.msg || '请求失败');
      }
    }
    
    // 如果不是ResultUtil格式，直接返回JSON
    return json as T;
  } catch (e: any) {
    // 网络错误：如果是第一次请求失败，标记后端不可用并降级到 Mock
    // 但只有在明确是连接错误时才降级
    const isNetworkError = e.name === 'AbortError' || 
        e.name === 'TypeError' ||
        e.message?.includes('Failed to fetch') || 
        e.message?.includes('NetworkError') || 
        e.message?.includes('ERR_CONNECTION_REFUSED') ||
        e.message?.includes('ECONNREFUSED') ||
        e.message?.includes('Network request failed') ||
        e.message?.includes('fetch') ||
        (e.name === 'TypeError' && e.message?.includes('网络'));
    
    if (isNetworkError && useBackend) {
      useBackend = false;
      const mockError = new Error('USE_MOCK_DATA') as any;
      mockError.isMock = true;
      mockError.path = path;
      mockError.init = init;
      throw mockError;
    }
    
    // 其他错误直接抛出（如业务逻辑错误）
    throw e;
  }
}


